package task

import (
	"channel/task_pool/errors"
	"context"
	"fmt"
	"runtime"
)

var PanicBuffLen = 2048

type Task interface {
	Run(ctx context.Context) error
}

// ToTaskFunc 包装用户普通方法成为Task
type ToTaskFunc func(ctx context.Context) error

func (fn ToTaskFunc) Run(ctx context.Context) error {
	return fn(ctx)
}

type Wrapper struct {
	Task Task
}

func (w *Wrapper) Run(ctx context.Context) (err error) {
	defer func() {
		if r := recover(); r != nil {
			buf := make([]byte, 0, PanicBuffLen)
			buf = buf[:runtime.Stack(buf, false)]
			err = fmt.Errorf("%w: %s", errors.ErrTaskRunningPanic, fmt.Sprintf("[PANIC]:\t%+v\n%s\n", r, buf))
		}
	}()
	return w.Task.Run(ctx)
}
